<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
<title>微信小程序.md</title><link href='https://fonts.googleapis.com/css?family=PT+Serif:400,400italic,700,700italic&subset=latin,cyrillic-ext,cyrillic,latin-ext' rel='stylesheet' type='text/css'><style type='text/css'>html, body {overflow-x: initial !important;}.CodeMirror { height: auto; }
.CodeMirror-scroll { overflow-y: hidden; overflow-x: auto; }
.CodeMirror-lines { padding: 4px 0px; }
.CodeMirror pre { }
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { background-color: white; }
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background-color: rgb(247, 247, 247); white-space: nowrap; }
.CodeMirror-linenumbers { }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.CodeMirror div.CodeMirror-cursor { border-left: 1px solid black; z-index: 3; }
.CodeMirror div.CodeMirror-secondarycursor { border-left: 1px solid silver; }
.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { width: auto; border: 0px; background: rgb(119, 238, 119); z-index: 1; }
.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite { }
.cm-tab { display: inline-block; }
.cm-s-typora-default .cm-header, .cm-s-typora-default .cm-property { color: rgb(217, 79, 138); }
.cm-s-typora-default pre.cm-header1:not(.cm-atom) :not(.cm-overlay) { font-size: 2rem; line-height: 2rem; }
.cm-s-typora-default pre.cm-header2:not(.cm-atom) :not(.cm-overlay) { font-size: 1.4rem; line-height: 1.4rem; }
.cm-s-typora-default .cm-atom, .cm-s-typora-default .cm-number { color: rgb(149, 132, 134); }
.cm-s-typora-default .cm-table-row, .cm-s-typora-default .cm-block-start { font-family: monospace; }
.cm-s-typora-default .cm-comment, .cm-s-typora-default .cm-code { color: rgb(74, 90, 159); font-family: monospace; }
.cm-s-typora-default .cm-tag { color: rgb(169, 68, 66); }
.cm-s-typora-default .cm-string { color: rgb(126, 134, 169); }
.cm-s-typora-default .cm-link { color: rgb(196, 122, 15); text-decoration: underline; }
.cm-s-typora-default .cm-variable-2, .cm-s-typora-default .cm-variable-1 { color: inherit; }
.cm-s-typora-default .cm-overlay { font-size: 1rem; font-family: monospace; }
.CodeMirror.cm-s-typora-default div.CodeMirror-cursor { border-left: 3px solid rgb(228, 98, 154); }
.cm-s-typora-default .CodeMirror-activeline-background { left: -60px; right: -30px; background: rgba(204, 204, 204, 0.2); }
.cm-s-typora-default .CodeMirror-gutters { border-right: none; background-color: inherit; }
.cm-s-typora-default .cm-trailing-space-new-line::after, .cm-startspace::after, .cm-starttab .cm-tab::after { content: "•"; position: absolute; left: 0px; opacity: 0; font-family: LetterGothicStd, monospace; }
.os-windows .cm-startspace::after, .os-windows .cm-starttab .cm-tab::after { left: -0.1em; }
.cm-starttab .cm-tab::after { content: " "; }
.cm-startspace, .cm-tab, .cm-starttab, .cm-trailing-space-a, .cm-trailing-space-b, .cm-trailing-space-new-line { font-family: monospace; position: relative; }
.cm-s-typora-default .cm-trailing-space-new-line::after { content: "↓"; opacity: 0.3; }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: black; }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-property { color: black; }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: blue; }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: bold; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: rgb(255, 0, 0); }
.cm-invalidchar { color: rgb(255, 0, 0); }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { margin-bottom: -30px; margin-right: -30px; padding-bottom: 30px; padding-right: 30px; height: 100%; outline: none; position: relative; box-sizing: content-box; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { position: absolute; z-index: 6; display: none; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow-x: hidden; overflow-y: scroll; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow-y: hidden; overflow-x: scroll; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 30px; z-index: 3; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: transparent; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; word-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
.CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
.CodeMirror-linebackground { position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-widget { }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.CodeMirror-selected { background: rgb(217, 217, 217); }
.CodeMirror-focused .CodeMirror-selected { background: rgb(215, 212, 240); }
.cm-searching { background: rgba(255, 255, 0, 0.4); }
.CodeMirror span { }
@media print { 
  .CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}
.CodeMirror-lint-markers { width: 16px; }
.CodeMirror-lint-tooltip { background-color: infobackground; border: 1px solid black; border-radius: 4px; color: infotext; font-family: monospace; overflow: hidden; padding: 2px 5px; position: fixed; white-space: pre-wrap; z-index: 10000; max-width: 600px; opacity: 0; transition: opacity 0.4s; font-size: 0.8em; }
.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning { background-position: left bottom; background-repeat: repeat-x; }
.CodeMirror-lint-mark-error { background-image: url(""); }
.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { background-position: center center; background-repeat: no-repeat; cursor: pointer; display: inline-block; height: 16px; width: 16px; vertical-align: middle; position: relative; }
.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { padding-left: 18px; background-position: left top; background-repeat: no-repeat; }
.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { background-image: url(""); }
.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { background-image: url(""); }
.CodeMirror-lint-marker-multiple { background-image: url(""); background-repeat: no-repeat; background-position: right bottom; width: 100%; height: 100%; }


html { font-size: 14px; background-color: rgb(255, 255, 255); color: rgb(51, 51, 51); }
body { margin: 0px; padding: 0px; height: auto; bottom: 0px; top: 0px; left: 0px; right: 0px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 1rem; line-height: 1.42857; overflow-x: hidden; background: inherit; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { background: rgb(181, 214, 252); text-shadow: none; }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; padding-bottom: 70px; white-space: pre-wrap; overflow-x: auto; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
@media screen and (max-width: 500px) { 
  body.typora-export { padding-left: 0px; padding-right: 0px; }
  .CodeMirror-sizer { margin-left: 0px !important; }
  .CodeMirror-gutters { display: none !important; }
}
.typora-export #write { margin: 0px auto; }
#write > p:first-child, #write > ul:first-child, #write > ol:first-child, #write > pre:first-child, #write > blockquote:first-child, #write > div:first-child, #write > table:first-child { margin-top: 30px; }
#write li > table:first-child { margin-top: -20px; }
img { max-width: 100%; vertical-align: middle; }
input, button, select, textarea { color: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
::before, ::after, * { box-sizing: border-box; }
#write p, #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write div, #write pre { width: inherit; }
#write p, #write h1, #write h2, #write h3, #write h4, #write h5, #write h6 { position: relative; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
p { -webkit-margin-before: 1rem; -webkit-margin-after: 1rem; -webkit-margin-start: 0px; -webkit-margin-end: 0px; }
.mathjax-block { margin-top: 0px; margin-bottom: 0px; -webkit-margin-before: 0rem; -webkit-margin-after: 0rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: bold; font-style: italic; }
a { cursor: pointer; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; margin: 4px 0px 0px; }
tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 80px; }
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
pre { white-space: pre-wrap; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
.md-diagram-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
.md-fences .CodeMirror.CodeMirror-wrap { top: -1.6em; margin-bottom: -1.6em; }
.md-fences.mock-cm { white-space: pre-wrap; }
.show-fences-line-number .md-fences { padding-left: 0px; }
.show-fences-line-number .md-fences.mock-cm { padding-left: 40px; }
.footnotes { opacity: 0.8; font-size: 0.9rem; padding-top: 1em; padding-bottom: 1em; }
.footnotes + .footnotes { margin-top: -1em; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: transparent; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: normal; text-align: left; box-sizing: content-box; direction: ltr; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li p, li .mathjax-block { margin: 0.5rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; }
@media print { 
  html, body { height: 100%; }
  .typora-export * { -webkit-print-color-adjust: exact; }
  h1, h2, h3, h4, h5, h6 { break-after: avoid-page; orphans: 2; }
  p { orphans: 4; }
  html.blink-to-pdf { font-size: 13px; }
  .typora-export #write { padding-left: 1cm; padding-right: 1cm; }
  .typora-export #write::after { height: 0px; }
  @page { margin: 20mm 0mm; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 2.86rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p .md-image:only-child { display: inline-block; width: 100%; text-align: center; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.mathjax-block { white-space: pre; overflow: hidden; width: 100%; }
p + .mathjax-block { margin-top: -1.143rem; }
.mathjax-block:not(:empty)::after { display: none; }
[contenteditable="true"]:active, [contenteditable="true"]:focus { outline: none; box-shadow: none; }
.task-list { list-style-type: none; }
.task-list-item { position: relative; padding-left: 1em; }
.task-list-item input { position: absolute; top: 0px; left: 0px; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc::after, .md-toc-content::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); text-decoration: none; }
.md-toc-inner:hover { }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: bold; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) { 
  .md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
  .md-toc-h4 .md-toc-inner { margin-left: 5em; }
  .md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
  .md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
.md-tag { opacity: 0.5; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: monospace; }
code { text-align: left; }
h1 .md-tag, h2 .md-tag, h3 .md-tag, h4 .md-tag, h5 .md-tag, h6 .md-tag { font-weight: initial; opacity: 0.35; }
a.md-print-anchor { border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: none !important; background: transparent !important; text-decoration: initial !important; text-shadow: initial !important; }
.md-inline-math .MathJax_SVG .noError { display: none !important; }
.mathjax-block .MathJax_SVG_Display { text-align: center; margin: 1em 0em; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; display: block !important; }
.MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; }
.MathJax_SVG .MJX-monospace { font-family: monospace; }
.MathJax_SVG .MJX-sans-serif { font-family: sans-serif; }
.MathJax_SVG { display: inline; font-style: normal; font-weight: normal; line-height: normal; zoom: 90%; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; }
.MathJax_SVG * { transition: none; }


@font-face { font-family: "PT Serif"; font-style: normal; font-weight: normal; src: local("PT Serif"), local("PTSerif-Regular"), url("./newsprint/PT_Serif-Web-Regular.ttf"); }
@font-face { font-family: "PT Serif"; font-style: italic; font-weight: normal; src: local("PT Serif"), local("PTSerif-Italic"), url("./newsprint/PT_Serif-Web-Italic.ttf"); }
@font-face { font-family: "PT Serif"; font-style: normal; font-weight: bold; src: local("PT Serif"), local("PTSerif-Bold"), url("./newsprint/PT_Serif-Web-Bold.ttf"); }
@font-face { font-family: "PT Serif"; font-style: italic; font-weight: bold; src: local("PT Serif"), local("PTSerif-BoldItalic"), url("./newsprint/PT_Serif-Web-BoldItalic.ttf"); }
html { font-size: 16px; }
html, body { background-color: rgb(243, 242, 238); font-family: "PT Serif", "Times New Roman", Times; color: rgb(31, 9, 9); line-height: 1.5em; }
#write { max-width: 40em; }
ol, ul { list-style: none; }
blockquote, q { quotes: none; }
blockquote::before, blockquote::after, q::before, q::after { content: none; }
table { border-collapse: collapse; border-spacing: 0px; }
h1, h2, h3, h4, h5, h6 { font-weight: bold; }
h1 { font-size: 1.875em; line-height: 1.6em; margin-top: 2em; }
h2, h3 { font-size: 1.3125em; line-height: 1.15; margin-top: 2.28571em; margin-bottom: 1.15em; }
h3 { font-weight: normal; }
h4 { font-size: 1.125em; margin-top: 2.67em; }
h5, h6 { font-size: 1em; }
h1 { border-bottom: 1px solid; margin-bottom: 1.875em; padding-bottom: 0.8125em; }
a { text-decoration: none; color: rgb(6, 85, 136); }
a:hover, a:active { text-decoration: underline; }
p, blockquote, .md-fences { margin-bottom: 1.5em; }
h1, h2, h3, h4, h5, h6 { margin-bottom: 1.5em; }
blockquote { font-style: italic; border-left: 5px solid; margin-left: 2em; padding-left: 1em; }
ul, ol { margin: 0px 0px 1.5em 1.5em; }
ol li { list-style-type: decimal; list-style-position: outside; }
ul li { list-style-type: disc; list-style-position: outside; }
.md-meta, .md-before, .md-after { color: rgb(153, 153, 153); }
table { margin-bottom: 1.5em; font-size: 1em; }
thead th, tfoot th { padding: 0.25em 0.25em 0.25em 0.4em; text-transform: uppercase; }
th { text-align: left; }
td { vertical-align: top; padding: 0.25em 0.25em 0.25em 0.4em; }
code, .md-fences { background-color: rgb(218, 218, 218); padding-left: 1ch; padding-right: 1ch; }
.md-fences { margin-left: 2em; margin-bottom: 3em; }
.md-fences .CodeMirror.CodeMirror-wrap { top: -0.8em; }
pre, code, tt { font-size: 0.875em; line-height: 1.71428em; }
h1 { line-height: 1.3em; font-weight: normal; margin-bottom: 0.5em; }
p + ul, p + ol { margin-top: -1em; }
h3 + ul, h4 + ul, h5 + ul, h6 + ul, h3 + ol, h4 + ol, h5 + ol, h6 + ol { margin-top: 0.5em; }
li > ul, li > ol { margin-top: inherit; }
h2, h3 { margin-bottom: 0.75em; }
hr { border-top: none; border-right: none; border-bottom: 1px solid; border-left: none; }
h1 { border-color: rgb(197, 197, 197); }
blockquote { border-color: rgb(186, 186, 186); color: rgb(101, 101, 101); }
thead.md-table-edit { background-color: transparent; }
thead { background-color: rgb(218, 218, 218); }
tr:nth-child(2n) { background: rgb(232, 231, 231); }
hr { border-color: rgb(197, 197, 197); }
.task-list { padding-left: 1rem; }
.task-list-item { padding-left: 1.5rem; list-style-type: none; }
.task-list-item input::before { content: "√"; display: inline-block; width: 1.25rem; height: 1.6rem; vertical-align: middle; text-align: center; color: rgb(221, 221, 221); background-color: rgb(243, 242, 238); }
.task-list-item input:checked::before, .task-list-item input[checked]::before { color: inherit; }
#write pre.md-meta-block { min-height: 1.875rem; color: rgb(85, 85, 85); border: 0px; background: transparent; margin-left: 1em; margin-top: 1em; }
.md-image > .md-meta { color: rgb(155, 81, 70); }
.md-expand.md-image > .md-meta { background-color: rgba(255, 255, 255, 0.65098); }
.md-image > .md-meta { font-family: Menlo, "Ubuntu Mono", Consolas, "Courier New", "Microsoft Yahei", "Hiragino Sans GB", "WenQuanYi Micro Hei", sans-serif; }
#write > h3.md-focus::before { left: -1.5rem; color: rgb(153, 153, 153); border-color: rgb(153, 153, 153); }
#write > h4.md-focus::before { left: -1.5rem; top: 0.25rem; color: rgb(153, 153, 153); border-color: rgb(153, 153, 153); }
#write > h5.md-focus::before { left: -1.5rem; color: rgb(153, 153, 153); border-color: rgb(153, 153, 153); }
#write > h6.md-focus::before { left: -1.5rem; top: 0.3125rem; color: rgb(153, 153, 153); border-color: rgb(153, 153, 153); }
.md-toc:focus .md-toc-content { margin-top: 19px; }
.md-toc-content:empty::before { color: rgb(6, 85, 136); }
.md-toc-item { color: rgb(6, 85, 136); }
#write div.md-toc-tooltip { background-color: rgb(243, 242, 238); }
#outline-dropmenu { background-color: rgb(243, 242, 238); box-shadow: rgba(0, 0, 0, 0.372549) 0px 6px 12px; }
.pin-outline #outline-dropmenu { background: inherit; box-shadow: none; border-right: 1px dashed; }
.pin-outline #outline-dropmenu:hover .outline-title-wrapper { border-left: 1px dashed; }
.outline-item:hover { background-color: rgb(218, 218, 218); border-left: 28px solid rgb(218, 218, 218); border-right: 18px solid rgb(218, 218, 218); }
.typora-node .outline-item:hover { border-right: 28px solid rgb(218, 218, 218); }
.outline-expander::before { content: ""; font-family: FontAwesome; font-size: 14px; top: 1px; }
.outline-expander:hover::before, .outline-item-open > .outline-item > .outline-expander::before { content: ""; }
.modal-content { background-color: rgb(243, 242, 238); }
.auto-suggest-container ul li { list-style-type: none; }
.megamenu-menu, #top-titlebar, #top-titlebar *, .megamenu-content { background: rgb(243, 242, 238); color: rgb(31, 9, 9); }
.megamenu-menu-header { border-bottom: 1px dashed rgb(32, 43, 51); }
.megamenu-menu { box-shadow: none; border-right: 1px dashed; }
header, .context-menu, .megamenu-content, footer { font-family: "PT Serif", "Times New Roman", Times; color: rgb(31, 9, 9); }
#megamenu-back-btn { color: rgb(31, 9, 9); border-color: rgb(31, 9, 9); }
.megamenu-menu-header #megamenu-menu-header-title::before { color: rgb(31, 9, 9); }
.megamenu-menu-list li a:hover, .megamenu-menu-list li a.active { color: inherit; background-color: rgb(232, 231, 223); }
.long-btn:hover { background-color: rgb(232, 231, 223); }
#recent-file-panel tbody tr:nth-child(2n-1) { background-color: transparent !important; }
.megamenu-menu-panel tbody tr:hover td:nth-child(2) { color: inherit; }
.megamenu-menu-panel .btn { background-color: rgb(210, 209, 209); }
.btn-default { background-color: transparent; }
.typora-sourceview-on #toggle-sourceview-btn, .show-word-count #footer-word-count { background: rgb(199, 197, 197); }
#typora-quick-open { background-color: inherit; }
.md-diagram-panel { margin-left: -1ch; margin-top: 24px; }






</style>
</head>
<body class='typora-export' >
<div  id='write'  class = 'is-node'><h1><a name='header-c1' class='md-header-anchor '></a>业务角度认识小程序：</h1><ul><li>让服务“触手可及”</li></ul><h1><a name='header-c10' class='md-header-anchor '></a>技术角度认识小程序</h1><ul><li>移动应用开发平台</li><li>适合做用完即走的应用（目的明确）</li></ul><h1><a name='header-c18' class='md-header-anchor '></a>快速体验</h1><p>手机微信扫描二维码：</p><p><img src='./img/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%B9%B3%E5%8F%B0.png' alt='' /></p><h1><a name='header-c23' class='md-header-anchor '></a>注册小程序账号</h1><h2><a name='header-c24' class='md-header-anchor '></a>微信公众平台官网</h2><p><a href='https://developers.weixin.qq.com/' target='_blank' >https://developers.weixin.qq.com/</a></p><h2><a name='header-c27' class='md-header-anchor '></a>AppID(小程序ID)</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>wxbfc536def1b7bad8</pre><ul><li>注册完=》设置=》拿到小程序开发ID</li></ul><h2><a name='header-c33' class='md-header-anchor '></a>下载安装小程序开发工具：</h2><p><a href='https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html' target='_blank' >https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html</a></p><h2><a name='header-c36' class='md-header-anchor '></a>安装注意</h2><ul><li>路径改为英文</li></ul><h1><a name='header-c41' class='md-header-anchor '></a>开发工具基本使用</h1><h2><a name='header-c42' class='md-header-anchor '></a>小程序项目结构</h2><ul><li>主界面 - 其他页面 - 来回导航 =》 组成完整业务</li></ul><p><img src='./img/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84.png' alt='' /></p><ul><li>小程序页面基本结构分析</li></ul><p><img src='./img/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%842.png' alt='' /></p><h2><a name='header-c55' class='md-header-anchor '></a>页面文件的组成</h2><p><img src='./img/%E9%A1%B5%E9%9D%A2%E6%96%87%E4%BB%B6%E7%BB%84%E6%88%90.png' alt='' /></p><ul><li><p>设置启动页面</p><pre class='md-fences mock-cm' style='display:block;position:relative'>app.json文件中：
&quot;pages&quot;:[
    &quot;pages/foo/foo&quot;,
    &quot;pages/index/index&quot;,
    &quot;pages/logs/logs&quot;
  ]</pre><p>​</p></li></ul><h1><a name='header-c65' class='md-header-anchor '></a>小程序配置</h1><p><a href='https://developers.weixin.qq.com/miniprogram/dev/framework/config.html' target='_blank' >https://developers.weixin.qq.com/miniprogram/dev/framework/config.html</a></p><h2><a name='header-c68' class='md-header-anchor '></a>1、app.json</h2><ul><li><p><code>app.json</code>文件用来对微信小程序进行全局配置，决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等</p><pre class='md-fences mock-cm' style='display:block;position:relative'>{
  &quot;pages&quot;: [
    &quot;pages/index/index&quot;,
    &quot;pages/logs/index&quot;
  ],
  &quot;window&quot;: {
    &quot;navigationBarTitleText&quot;: &quot;Demo&quot;
  },
  &quot;tabBar&quot;: {
    &quot;list&quot;: [{
      &quot;pagePath&quot;: &quot;pages/index/index&quot;,
      &quot;text&quot;: &quot;首页&quot;
    }, {
      &quot;pagePath&quot;: &quot;pages/logs/logs&quot;,
      &quot;text&quot;: &quot;日志&quot;
    }]
  },
  &quot;networkTimeout&quot;: {
    &quot;request&quot;: 10000,
    &quot;downloadFile&quot;: 10000
  },
  &quot;debug&quot;: true
}</pre></li></ul><h3><a name='header-c74' class='md-header-anchor '></a>app.json 配置项列表</h3><table><thead><tr><th>属性</th><th>类型</th><th>必填</th><th>描述</th></tr></thead><tbody><tr><td><a href='https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#window'>window</a></td><td>Object</td><td>否</td><td>设置默认页面的窗口表现</td></tr><tr><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td></tr><tr><td></td><td></td><td></td><td></td></tr></tbody></table><table><thead><tr><th>属性</th><th>类型</th><th>必填</th><th>描述</th></tr></thead><tbody><tr><td><a href='https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#pages'>pages</a></td><td>String Array</td><td>是</td><td>设置页面路径</td></tr><tr><td><a href='https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#window'>window</a></td><td>Object</td><td>否</td><td>设置默认页面的窗口表现</td></tr><tr><td><a href='https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#tabbar'>tabBar</a></td><td>Object</td><td>否</td><td>设置底部 tab 的表现</td></tr><tr><td><a href='https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#networktimeout'>networkTimeout</a></td><td>Object</td><td>否</td><td>设置网络超时时间</td></tr><tr><td><a href='https://developers.weixin.qq.com/miniprogram/dev/framework/config.html#debug'>debug</a></td><td>Boolean</td><td>否</td><td>设置是否开启 debug 模式</td></tr></tbody></table><h4><a name='header-c132' class='md-header-anchor '></a>window</h4><ul><li>用于设置小程序的状态栏、导航条、标题、窗口背景色。</li></ul><table><thead><tr><th>属性</th><th>类型</th><th>默认值</th><th>描述</th><th>最低版本</th></tr></thead><tbody><tr><td>navigationBarBackgroundColor</td><td>HexColor</td><td>#000000</td><td>导航栏背景颜色，如&quot;#000000&quot;</td><td></td></tr><tr><td>navigationBarTextStyle</td><td>String</td><td>white</td><td>导航栏标题颜色，仅支持 black/white</td><td></td></tr><tr><td>navigationBarTitleText</td><td>String</td><td></td><td>导航栏标题文字内容</td><td></td></tr><tr><td>navigationStyle</td><td>String</td><td>default</td><td>导航栏样式，仅支持 default/custom。custom 模式可自定义导航栏，只保留右上角胶囊状的按钮</td><td>微信版本 6.6.0</td></tr><tr><td>backgroundColor</td><td>HexColor</td><td>#ffffff</td><td>窗口的背景色</td><td></td></tr><tr><td>backgroundTextStyle</td><td>String</td><td>dark</td><td>下拉 loading 的样式，仅支持 dark/light</td><td></td></tr><tr><td>backgroundColorTop</td><td>String</td><td>#ffffff</td><td>顶部窗口的背景色，仅 iOS 支持</td><td>微信版本 6.5.16</td></tr><tr><td>backgroundColorBottom</td><td>String</td><td>#ffffff</td><td>底部窗口的背景色，仅 iOS 支持</td><td>微信版本 6.5.16</td></tr><tr><td>enablePullDownRefresh</td><td>Boolean</td><td>false</td><td>是否开启下拉刷新，详见<a href='https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page.html#%25E9%25A1%25B5%25E9%259D%25A2%25E7%259B%25B8%25E5%2585%25B3%25E4%25BA%258B%25E4%25BB%25B6%25E5%25A4%2584%25E7%2590%2586%25E5%2587%25BD%25E6%2595%25B0'>页面相关事件处理函数</a></td><td></td></tr><tr><td>onReachBottomDistance</td><td>Number</td><td>50</td><td>页面上拉触底事件触发时距页面底部距离，单位为px</td><td></td></tr></tbody></table><p></p><p>其他请参考官方文档：</p><ul><li><p>app.json 配置
&quot;debug&quot;:true  设置是否开启 debug 模式,上线后一定要改为false</p></li><li><p>页面的.json只能设置 window 相关的配置项，以决定本页面的窗口表现，所以无需写 window 这个键</p></li><li><p>app.json 配置：
&quot;debug&quot;:true  设置是否开启 debug 模式,上线后一定要改为false</p><p>页面的.json只能设置 window 相关的配置项，以决定本页面的窗口表现，所以无需写 window 这个键</p></li></ul><h4><a name='header-c222' class='md-header-anchor '></a>知识点：</h4><ul><li><p>text: 行内元素</p></li><li><p>view: 块级元素</p></li><li><p>pages.json只能在页面中设置禁止滚动，因为页面一般都是可以滚动的</p><ul><li>disableScrollBoolean	false	设置为 true 则页面整体不能上下滚动；只在 page.json 中有效，无法在 app.json 中设置该项</li></ul></li></ul><h2><a name='header-c237' class='md-header-anchor '></a>tabBar（导航栏配置）</h2><ul><li>如果小程序是一个多 tab 应用（客户端窗口的底部或顶部有 tab 栏可以切换页面），可以通过 tabBar 配置项指定 tab 栏的表现，以及 tab 切换时显示的对应页面。</li></ul><h3><a name='header-c242' class='md-header-anchor '></a>Tip：</h3><ol start='' ><li>当设置 position 为 top 时，将不会显示 icon（就是图标），会变成标题切换栏</li><li>tabBar 中的 list 是一个数组，<strong>只能配置最少2个、最多5个 tab</strong>，tab 按数组的顺序排序。</li></ol><h3><a name='header-c250' class='md-header-anchor '></a>配置方式：</h3><ul><li><p>app.json中新增tabBar配置项</p><pre class='md-fences mock-cm' style='display:block;position:relative'>list属性（数组）
pagePath 页面路径//可以用来切换页面
iconPath（常规状态下图片）  图片相对路径
selectedIconPath(选中状态下的图片)  在当前页面生效
默认页面如果没有在tabBar中设置，那么当进入那个页面后
底部导航栏不会显示
图片新建一个assets目录保存</pre></li></ul><p>配置项：</p><table><thead><tr><th>属性</th><th>类型</th><th>必填</th><th>默认值</th><th>描述</th></tr></thead><tbody><tr><td>color</td><td>HexColor</td><td>是</td><td></td><td>tab 上的文字默认颜色</td></tr><tr><td>selectedColor</td><td>HexColor</td><td>是</td><td></td><td>tab 上的文字选中时的颜色</td></tr><tr><td>backgroundColor</td><td>HexColor</td><td>是</td><td></td><td>tab 的背景色</td></tr><tr><td>borderStyle</td><td>String</td><td>否</td><td>black</td><td>tabbar上边框的颜色， 仅支持 black/white</td></tr><tr><td>list</td><td>Array</td><td>是</td><td></td><td>tab 的列表，详见 list 属性说明，最少2个、最多5个 tab</td></tr><tr><td>position</td><td>String</td><td>否</td><td>bottom</td><td>可选值 bottom、top</td></tr></tbody></table><h4><a name='header-c301' class='md-header-anchor '></a>其中list配置项：</h4><table><thead><tr><th>属性</th><th>类型</th><th>必填</th><th>说明</th></tr></thead><tbody><tr><td>pagePath</td><td>String</td><td>是</td><td>页面路径，必须在 pages 中先定义</td></tr><tr><td>text</td><td>String</td><td>是</td><td>tab 上按钮文字</td></tr><tr><td>iconPath</td><td>String</td><td>否</td><td>图片路径，icon 大小限制为40kb，建议尺寸为 81px * 81px，当 postion 为 top 时，此参数无效，不支持网络图片</td></tr><tr><td>selectedIconPath</td><td>String</td><td>否</td><td>选中时的图片路径，icon 大小限制为40kb，建议尺寸为 81px * 81px ，当 postion 为 top 时，此参数无效</td></tr></tbody></table><pre class='md-fences mock-cm' style='display:block;position:relative'>&quot;tabBar&quot;: {
    &quot;color&quot;:&quot;#666&quot;,
    &quot;backgroundColor&quot;:&quot;#ccc&quot;,
    &quot;position&quot;: &quot;top&quot;,
    &quot;list&quot;: [{
      &quot;pagePath&quot;: &quot;pages/index/index&quot;,
      &quot;text&quot;: &quot;首页&quot;,
      &quot;iconPath&quot;: &quot;assets/board.png&quot;,
      &quot;selectedIconPath&quot;: &quot;assets/board-actived.png&quot;
    },
    {
      &quot;pagePath&quot;: &quot;pages/foo/foo&quot;,
      &quot;text&quot;: &quot;自己&quot;,
      &quot;iconPath&quot;: &quot;assets/home.png&quot;,
      &quot;selectedIconPath&quot;: &quot;assets/home-actived.png&quot;
    }
    ]
  }</pre><h1><a name='header-c329' class='md-header-anchor '></a>小程序框架：</h1><h2><a name='header-c330' class='md-header-anchor '></a>逻辑与页面分离结构</h2><ol start='' ><li>逻辑层  js完成，处理生命周期，业务数据供给，界面事件处理</li><li>视图层  页面结构wxml，页面样式wxss，展示逻辑层数据，接收用户输入</li></ol><h2><a name='header-c338' class='md-header-anchor '></a>逻辑层 js</h2><ul><li><p>web中js不太一样</p><pre class='md-fences mock-cm' style='display:block;position:relative'>web 中：
  ECMAScript webapi: DOM BOM 
WeiXin：
　ECMAScript weixin api 文件 网络 媒体 etc.</pre></li></ul><h1><a name='header-c345' class='md-header-anchor '></a>生命周期</h1><ul><li>把过程划分很多阶段，某个阶段结束后发送消息告诉程序，当前执行的位置。</li><li>在特定的阶段或者时间执行特定代码</li></ul><h2><a name='header-c353' class='md-header-anchor '></a>应用生命周期</h2><h3><a name='header-c354' class='md-header-anchor '></a>添加app.json</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>写入 {}  因为json文件
加入pages属性：数组，定义所有页面，第一个为默认启动页面
 &quot;pages&quot;: [
	&quot;pages/index/index&quot;  //会自动创建文件
]</pre><h3><a name='header-c356' class='md-header-anchor '></a>新建app.js</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>// 每一个 JS 都有单独的作用域
// const foo = &#39;123&#39;

// 用于去创建一个应用实例对象
App({
  // 在整个应用启动时触发
  // 只会触发一次
  onLaunch: function (options) {
    console.log(&#39;应用启动了&#39;)
  },
  // 应用程序显示到屏幕上
  // 每次成为焦点状态都会触发
  onShow: function (options) {
    console.log(&#39;应用前台显示了&#39;)
    console.log(options)
  },
  onHide: function () {
    console.log(&#39;隐藏到后台&#39;)
  },
  // onError 只能捕获到运行阶段的异常
  onError: function (msg) {
    console.log(msg)
  },

  // 除了生命周期里面约定的 钩子函数，还可以定义任何成员，
  // 定义在这里的成员可以在后续每一个页面中共享
  foo: &#39;bar&#39;,
  say () {
    console.log(&#39;hello&#39;)
  }
})</pre><h3><a name='header-c358' class='md-header-anchor '></a>在页面.js中</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>   /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // throw new Error(&#39;hello error&#39;)
    // 获取全局唯一的应用程序实例对象
    const app = getApp()//
    console.log(app.foo)//获取全局应用示例成员
	//获取全局应用示例的构造方法
    app.say()
  },</pre><h3><a name='header-c360' class='md-header-anchor '></a>抛出异常</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>throw new Error(&#39;hello error&#39;) //抛出异常</pre><h2><a name='header-c362' class='md-header-anchor '></a>页面生命周期</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>// 创建一个页面实例对象
Page({
  // 页面加载
  // 这个页面即将要工作了
  // 适合去做数据初始化
  onLoad() {
    console.log(&#39;index on load&#39;)
  },
  // 页面进入焦点状态（前台展示）
  onShow() {
    console.log(&#39;index on show&#39;)
  },
  // 当页面准备好了
  // 页面渲染完成
  onReady() {
    // 只有页面加载完成，才可以设置标题
    wx.setNavigationBarTitle({
      title: &#39;index页面&#39;
    })
  },
  onHide() {
    console.log(&#39;index on hide&#39;)
  },
  // 页面卸载
  // 当页面被销毁
  onUnload() {
    // 可以用于去在页面卸载之前保存页面状态
    console.log(&#39;index on unload&#39;)
  }
})</pre><h3><a name='header-c364' class='md-header-anchor '></a>补充：</h3><h4><a name='header-c365' class='md-header-anchor '></a>跳转链接标签</h4><pre class='md-fences mock-cm' style='display:block;position:relative'>跳转链接（类似a标签）
&lt;navigator url=&#39;/pages/page1/page1&#39;&gt;page1&lt;/navigator&gt;
点击会触发onHide事件</pre><h4><a name='header-c367' class='md-header-anchor '></a>初始化设置页面数据</h4><pre class='md-fences mock-cm' style='display:block;position:relative'>// 适合去做数据初始化
  data: {},
  onLoad() {
    this.setData({foo: &quot;hello food&quot;})
    console.log(this.data)
    console.log(&#39;page1 on load&#39;)
  },
  
  页面展示：
  &lt;text&gt;{{ foo }}&lt;/text&gt;</pre><h1><a name='header-c369' class='md-header-anchor '></a>数据绑定</h1><h2><a name='header-c370' class='md-header-anchor '></a>首先在js文件中设置data属性</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>data: {
    // 这个对象里面的所有属性都可以在界面中访问到
    message: &#39;hello world&#39;,
    // 在 data 中只能暴露数据成员,不能暴露出方法
    addPostfix: function (input) {
      return input + &#39;1&#39;
    }
  }</pre><h2><a name='header-c372' class='md-header-anchor '></a>然后页面通过花括号接收数据</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;view class=&quot;container&quot;&gt;
  &lt;!-- mustache 小胡子语法 专门用于输出逻辑层暴露的数据 --&gt;
  &lt;text&gt;{{message}}&lt;/text&gt;
  &lt;!-- mustache 可以作用在 元素的 内容和 属性上 --&gt;
  &lt;input value=&quot;{{message}}&quot;/&gt;
&lt;/view&gt;</pre><h2><a name='header-c374' class='md-header-anchor '></a>接收方法，使用wxs新标签，类似script标签</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;!-- wxs 标签 类似于 咱们在 html 中的 script 标签，可以定义一些行内脚本 --&gt;
&lt;wxs module=&quot;foo&quot;&gt;
  // 这里可以到处一个对象，这个对象可以直接在界面上使用
  // 这里的代码必须遵循 commonjs 规范
  module.exports = {
    addPostfix: function (input) {
      return input + &#39; wxs&#39;
    }
  }
&lt;/wxs&gt;

页面标签接收：
&lt;text&gt;{{foo.addPostfix(message)}}&lt;/text&gt;</pre><h2><a name='header-c376' class='md-header-anchor '></a>总结：</h2><ul><li><p>wxml中属性的值 如果只是在 双引号 它永远是字符串</p></li><li><p>在 data 中只能暴露数据成员,不能暴露出方法</p><p>​</p></li></ul><h1><a name='header-c386' class='md-header-anchor '></a>条件控制属性（指令）</h1><h2><a name='header-c387' class='md-header-anchor '></a>1、设置页面数据即，生命钩子函数</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>Page({
  data: {
    isLoading: true
  },
  onReady () {//页面渲染完成
    setTimeout(() =&gt; {
      this.setData({ isLoading: false })
    }, 2000)
  }
})</pre><p></p><h2><a name='header-c391' class='md-header-anchor '></a>2、wx:if 、 wx:else 以及 wx:elif</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;view wx:if=&quot;{{ isLoading }}&quot;&gt;
  &lt;text&gt;loading...&lt;/text&gt;
&lt;/view&gt;
&lt;view wx:else&gt;
  &lt;text&gt;welcome Mr.Xiong&lt;/text&gt;
&lt;/view&gt;

wx:elif=&quot;&quot;  &lt;==&gt;else if</pre><h3><a name='header-c393' class='md-header-anchor '></a>注意：对于频繁需要被切换显示的元素，不应该使用 wx:if</h3><p>​	         类似angular 的 v-if / v-show</p><h2><a name='header-c396' class='md-header-anchor '></a>3、小程序提供了hidden</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>所以小程序提供了hidden：隐藏 --&gt;
&lt;view hidden=&quot;{{!isLoading}}&quot;&gt; hidden == false不隐藏
  &lt;text&gt;loading...&lt;/text&gt;
&lt;/view&gt;
&lt;view hidden=&quot;{{isLoading}}&quot;&gt;
  &lt;text&gt;welcome Mr.Xiong&lt;/text&gt;
&lt;/view&gt;</pre><h2><a name='header-c398' class='md-header-anchor '></a>4、案例：</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;!-- 案例：当一个view中有两个text需要隐藏显示 --&gt;
&lt;view&gt;
  &lt;text wx:if=&quot;{{ isLoading }}&quot;&gt;hello&lt;/text&gt;
  &lt;text wx:if=&quot;{{ isLoading }}&quot;&gt; word&lt;/text&gt;
&lt;/view&gt;

&lt;!-- 优化1 只有两个text时候--&gt;
&lt;view wx:if=&quot;{{ isLoading }}&quot;&gt;
  &lt;text&gt;hello&lt;/text&gt;
  &lt;text&gt; word&lt;/text&gt;
&lt;/view&gt;

&lt;!-- 优化2 block标签--&gt;
&lt;view&gt;
  &lt;block wx:if=&quot;{{ isLoading }}&quot;&gt;
    &lt;text&gt;hello&lt;/text&gt;
    &lt;text&gt; word&lt;/text&gt;
  &lt;/block&gt;
  &lt;text&gt;不想隐藏&lt;/text&gt;
&lt;/view&gt;</pre><h1><a name='header-c400' class='md-header-anchor '></a>列表控制属性</h1><h2><a name='header-c401' class='md-header-anchor '></a>1、自定义虚拟数据</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>data: {
    student: [
      { id: 1, name: &#39;小刚刚&#39;, age: 18 },
      { id: 2, name: &#39;小灰灰&#39;, age: 18 },
      { id: 3, name: &#39;小蕉蕉&#39;, age: 18 }
    ]
  }</pre><h2><a name='header-c403' class='md-header-anchor '></a>2、页面循环渲染</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;view&gt;
  &lt;view wx:for=&quot;{{ student }}&quot; wx:for-item=&quot;v&quot; wx:for-index=&quot;i&quot; wx:key=&quot;id&quot;&gt;
    &lt;checkbox /&gt;
    &lt;text&gt;序号{{i&gt;=10?i:&#39;0&#39;+i}}-姓名：{{v.name}}-年龄：{{v.age&gt;=10?v.age:&#39;0&#39;+v.age}}&lt;/text&gt;
  &lt;/view&gt;
  &lt;button bindtap=&#39;addItemHandle&#39;&gt;新增&lt;/button&gt;
&lt;/view&gt;</pre><h3><a name='header-c405' class='md-header-anchor '></a>知识点：</h3><h4><a name='header-c406' class='md-header-anchor '></a>1、添加属性：wx:key=&quot;id&quot;</h4><pre class='md-fences mock-cm' style='display:block;position:relative'>//属性值写的是数据成员属性名称
//或者当没有成员属性值时*this保留值指定当前被遍历函数</pre><h4><a name='header-c408' class='md-header-anchor '></a>2、给按钮添加触摸点击事件</h4><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;button bindtap=&quot;addItemHandle&quot;&gt;add&lt;button&gt;</pre><h4><a name='header-c410' class='md-header-anchor '></a>3、页面.js中</h4><ul><li>//页面对象上除了钩子函数之外，可以定义其他任意函数</li><li>//这些函数可以作为视图层（界面）元素处理函数</li></ul><h4><a name='header-c418' class='md-header-anchor '></a>拓展：</h4><ul><li>如果随便传字符串进去，那么会把字符串分隔 打印出来</li><li><text wx:for="foo">{{item}}</text></li></ul><h1><a name='header-c426' class='md-header-anchor '></a>事件处理</h1><h2><a name='header-c427' class='md-header-anchor '></a>1、点击事件：必须通过标签属性指定</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;button bindtap=&quot;事件函数名&quot;&gt;&lt;/button&gt;</pre><h2><a name='header-c429' class='md-header-anchor '></a>2、e.timestamp:触摸 和 页面渲染完成时的时间差</h2><h2><a name='header-c430' class='md-header-anchor '></a>3、冒泡现象：</h2><ul><li><p>当父级元素也有点击事件的时候就会产生</p><pre class='md-fences mock-cm' style='display:block;position:relative'>解决方法：
- 子元素的绑定方式改为: catchtap
- 这样就不会有冒泡了</pre></li></ul><h2><a name='header-c436' class='md-header-anchor '></a>4、给每个点击标签自定义data-属性</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>data-id=&quot;1&quot;
然后在逻辑层中
e.target.dataset.id可以获取到自定义属性</pre><h1><a name='header-c438' class='md-header-anchor '></a>单项数据流：</h1><ul><li>从逻辑层单向往界面层的一种绑定（this.setData()）</li><li>从界面层往逻辑层的一种单项的事件传递(e.detail.value)</li></ul><h2><a name='header-c446' class='md-header-anchor '></a>案例：双向绑定效果</h2><pre class='md-fences mock-cm' style='display:block;position:relative'>data: {
	foo: &quot;foo data&quot;
}

// 文本框值发生变化
** &lt;input type=&quot;text&quot; value=&quot;{{foo}}&quot; bindinput=&quot;inputChangeHandle&quot;/&gt;

inputChangeHandle(e){
	//将界面数据再次同步回数据源
	this.data.foo = e.detail.value

	//1、改变数据源，
	//2、通知框架，数据源变了，需要重新渲染页面
	this.setData({ foo:e.detail.value })
}
</pre><h2><a name='header-c448' class='md-header-anchor '></a>setData作用</h2><ul><li>1、变数据源，</li><li>2、通知框架，数据源变了，需要重新渲染页面</li></ul><h1><a name='header-c456' class='md-header-anchor '></a>WXSS  与  CSS</h1><ul><li>语法遵循CSS</li></ul><h2><a name='header-c461' class='md-header-anchor '></a>差异:扩展特性:</h2><h3><a name='header-c462' class='md-header-anchor '></a>1、单位尺寸 rpx  响应式像素，</h3><ul><li><p>自适应不管手机多大，约定屏幕宽度都是750rpx</p><pre class='md-fences mock-cm' style='display:block;position:relative'>传统：
.box {
	width: 50%;//屏幕宽度一半
	hight: 300px;
	background: #f40;
	}
	.child {
	width: 200%;//子盒子和屏幕一样宽
	}

/* pages/wxssTest/wxssTest.wxss */
.box {
  /* 屏幕宽度一半,因为约定不管手机多大，宽度都是750rpx */
  height: 200px;
  width: 375rpx;
  background-color: #f40;
}

.child {
  /* 子盒子和屏幕一样宽 */
  width: 750rpx;
  height: 200px;
  background-color: red;
}</pre><p>​</p></li></ul><p>2、样式导入 @import  &#39;&#39;</p><pre class='md-fences mock-cm' style='display:block;position:relative'>@import &quot;../../comon.wxss&quot;
用于某几个页面的公共样式时候
全局使用app.wxss</pre><h3><a name='header-c473' class='md-header-anchor '></a>1、weui-wxss样式库<a href='https://github.com/Tencent/weui-wxss' target='_blank' >https://github.com/Tencent/weui-wxss</a></h3><h3><a name='header-c474' class='md-header-anchor '></a>2、适合web开发：<a href='https://weui.io/' target='_blank' >https://weui.io/</a></h3><p></p><p></p><h1><a name='header-c479' class='md-header-anchor '></a>项目</h1><h2><a name='header-c480' class='md-header-anchor '></a>豆瓣项目</h2><h3><a name='header-c481' class='md-header-anchor '></a>1、将项目克隆到本地</h3><pre class='md-fences mock-cm' style='display:block;position:relative'># 定位到任意目录
$ cd path/to/root

# 克隆仓库到指定的文件夹
$ git clone https://github.com/zce/weapp-demo.git [project-name] -b master --depth 1

# 进入指定的文件夹
$ cd [project-name]</pre><h3><a name='header-c483' class='md-header-anchor '></a>2、安装项目<code>NPM</code>依赖</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>$ npm install</pre><h3><a name='header-c485' class='md-header-anchor '></a>3、开发阶段，启动监视</h3><pre class='md-fences mock-cm' style='display:block;position:relative'># 启动监视
$ npm run watch

或者：
yarn watch</pre><p></p><h3><a name='header-c489' class='md-header-anchor '></a>gulp工具，打包数据流</h3><h3><a name='header-c490' class='md-header-anchor '></a>文字教程：</h3><ul><li><a href='https://github.com/zce/weapp-demo/tree/tutorial' target='_blank' >https://github.com/zce/weapp-demo/tree/tutorial</a></li></ul><h2><a name='header-c495' class='md-header-anchor '></a>关于豆瓣API限制第三方小程序调用问题说明</h2><p>很多朋友最近都在反馈豆瓣接口 403 的问题，我抽空仔细排查了一遍，豆瓣官方应该是限制了第三方小程序对豆瓣接口的调用，对于这一行为我认为“无可厚非”，因为你没有为豆瓣的免费服务“买单”，请各位不要骂街。</p><p>为了帮助更多初学者或是爱好者，我个人准备了一个反向代理服务器（免费开放）。希望各位<strong>珍惜资源切勿滥用</strong>，谢谢！</p><p>接口地址：<a href='https://douban.uieee.com' target='_blank' >https://douban.uieee.com</a> （支持 HTTP / HTTPS）</p><p><strong>接口限流：10000 次 / 1 小时</strong>，由于是豆瓣官方的限流，所以所有使用我搭建的这个反向代理服务的朋友都是<strong>共享这 10000 次请求</strong>的，我也没办法再去提高这个数字（普通个人用户是 100 次 / 1 小时），所以还是希望大家不要滥用。</p><p>当然如果还是不幸超出额度的话，就只能等待下一个整点，不明白为什么的朋友，可以自己 Google 一下接口限流：API Rate Limit。</p><p>如果你可以的话，建议你自己参考我的配置文件配置一个自己的反向代理服务（这样就没人跟你抢了😀）</p><p>接口配置文件仓库：<a href='https://github.com/zce/douban-api-proxy' target='_blank' >https://github.com/zce/douban-api-proxy</a> (包括解决方法)</p><p></p><h2><a name='header-c512' class='md-header-anchor '></a>相关项目</h2><ul><li><a href='https://github.com/zce/weapp-douban'>zce/weapp-douban</a> - 不包含开发工作流版本的豆瓣电影</li><li><a href='https://github.com/zce/weapp-todos'>zce/weapp-todos</a> - 一个简单的任务清单小程序</li><li><a href='https://github.com/zce/weapp-locally'>zce/weapp-locally</a> - 本地生活，本地吃喝玩乐</li><li><del><a href='https://github.com/zce/weapp-boilerplate'>zce/weapp-boilerplate</a> - 一个小程序的快速开发骨架</del></li></ul><p></p><h1><a name='header-c528' class='md-header-anchor '></a>本地生活项目</h1><h2><a name='header-c529' class='md-header-anchor '></a>创建项目</h2><h3><a name='header-c530' class='md-header-anchor '></a>1、app.json</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>{
	&quot;pages/index/index&quot;，
	message,
	prifile
}</pre><h3><a name='header-c532' class='md-header-anchor '></a>2、window属性样式设置：</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>&quot;window&quot;: {
    &quot;navigationBarBackgroundColor&quot;: &quot;#3a4861&quot;, //导航条颜色#3a4861
    &quot;navigationBarTextStyle&quot;: &quot;white&quot;, //文本颜色white
    &quot;navigationBarTitleText&quot;: &quot;本地生活&quot;, //页面标题：本地生活
    &quot;backgroundColor&quot;: &quot;#bcc0c9&quot;, //下拉窗口背景颜色#bcc0c9
    &quot;backgroundTextStyle&quot;: &quot;light&quot;, //文本加载小球颜色：light亮色
    &quot;enablePullDownRefresh&quot;: false //是否启用下拉刷新，某个页面可以单独设置
  },</pre><h3><a name='header-c534' class='md-header-anchor '></a>3、底部导航栏 首页、消息、我的</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>tabBar:{
 &quot;list&quot;:[
	{
	&quot;pagePath&quot;:&quot;pages/index/index&quot;
	&quot;text&quot;: &quot;首页&quot;，
 	导航图标正常状态
	&quot;iconPath&quot;:&quot;asset/tabs/home.png&quot;
	&quot;selecedIconPath&quot;:&quot;导航图标选中样式&quot;
	}
 ]
}</pre><h3><a name='header-c536' class='md-header-anchor '></a>4、底部导航栏公共样式</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>&quot;tabBar&quot;: {
    &quot;color&quot;: &quot;#999&quot;,
    &quot;backgroundColor&quot;: &quot;#fff&quot;,
    &quot;selectedColor&quot;: &quot;#444&quot;,
    &quot;borderStyle&quot;: &quot;black&quot;,
    &quot;list&quot;: [
      {
        &quot;pagePath&quot;: &quot;pages/index/index&quot;,
        &quot;text&quot;: &quot;首页&quot;,
        &quot;iconPath&quot;: &quot;assets/home.png&quot;,
        &quot;selectedIconPath&quot;: &quot;assets/home-active.png&quot;
      }
}</pre><h3><a name='header-c538' class='md-header-anchor '></a>5、可以使用sublime编写小程序项目，有助于快速开发</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>1、可以安装插件
2、选中 - 查看 - 语法</pre><h3><a name='header-c540' class='md-header-anchor '></a>6、轮播图swiper</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>适合微信小程序的轮播图组件
&lt;swiper class=&quot;slides&quot;&gt;
	&lt;swiper-item&gt;
		&lt;image src=&quot;/assets/images/banner-01.png&quot; /&gt;
	&lt;/swiper-item&gt;
	&lt;swiper-item&gt;
		&lt;image src=&quot;/assets/images/banner-02.png&quot; /&gt;
	&lt;/swiper-item&gt;
&lt;/swiper&gt;
</pre><h3><a name='header-c542' class='md-header-anchor '></a>7、九宫格导航</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;!-- 九宫格导航按钮 --&gt;
&lt;view class=&quot;grids&quot;&gt;
  &lt;navigator url=&quot;/pages/cate/cate?cat={{item.id}}&quot; class=&quot;item&quot; wx:for=&quot;{{ categories }}&quot; wx:key=&quot;id&quot;&gt;
    &lt;image src=&quot;{{ item.icon}}&quot;&gt;&lt;/image&gt;
    &lt;text&gt;{{ item.name }}&lt;/text&gt;
  &lt;/navigator&gt;
&lt;/view&gt;</pre><h3><a name='header-c544' class='md-header-anchor '></a>8、底部导航按钮</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;!-- 底部按钮导航 --&gt;
&lt;view class=&#39;footer&#39;&gt;
  &lt;view class=&quot;btnlink&quot;&gt;
    &lt;image src=&quot;/assets/images/link-01.png&quot;&gt;&lt;/image&gt;
  &lt;/view&gt;
  &lt;view class=&quot;btnlink&quot;&gt;
    &lt;image src=&quot;/assets/images/link-02.png&quot;&gt;&lt;/image&gt;
  &lt;/view&gt;
&lt;/view&gt;</pre><h2><a name='header-c546' class='md-header-anchor '></a>9、小车程序中图片大小设置问题</h2><ul><li><p>1、小程序中宽高都有默认值，并不会只设置一个，另一个自适应</p></li><li><p>解决：官方文档 ，发现图片的 mode属性：</p><pre class='md-fences mock-cm' style='display:block;position:relative'>图片裁剪、缩放的模式；
mode 有效值：mode 有 13 种模式，其中 4 种是缩放模式，9 种是裁剪模式。
属性值：aspectFill
- 保持纵横比缩放图片，只保证图片的短边能完全显示出来。
- 也就是说，图片通常只在水平或垂直方向是完整的，
- 另一个方向将会发生截取。
&lt;image src=&quot;{{ item.image }}&quot; mode=&#39;aspectFill&#39;&gt;&lt;/image&gt;
</pre></li></ul><h3><a name='header-c555' class='md-header-anchor '></a>10、小程序发送http请求</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>wx.request({
	  这里的地址没有跨域概念
      url: &#39;https://locally.uieee.com/slides&#39;,
      header:{//请求头定义请求的数据类型
          &quot;Content-Type&quot;:&quot;json&quot;
      },
      success: res =&gt; {
        console.log(res)
        this.setData({ slides: res.data })
      }
    })</pre><h3><a name='header-c557' class='md-header-anchor '></a>11、接口地址：</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>1、九宫格接口：https://locally.uieee.com/categories
2、列表项：https://locally.uieee.com/categories/1/shops?_page=1&amp;_limit=10
3、搜索接口：https://locally.uieee.com/categories/1/shops?_page=1&amp;_limit=10&amp;q=鸡排</pre><h3><a name='header-c559' class='md-header-anchor '></a>12、优化请求方式：</h3><ul><li><p>因为请求域名都相同</p></li><li><p>根目录下新建utils目录，创建fetch.js文件</p></li><li><p>Promise 对象用于一个异步操作的最终完成（或失败）及其结果值的表示。简单点说，它就是用于处理异步操作的，异步处理成功了就执行成功的操作，异步处理失败了就捕获错误或者停止后续操作。</p><pre class='md-fences mock-cm' style='display:block;position:relative'>module.exports = (url, data) =&gt; {
  return new Promise((resolve, reject) =&gt; {
    wx.request({
      url: `https://locally.uieee.com/${url}`,//这里的地址没有跨域概念
      data: data,
      success: resolve,
      fail: reject
    })
  })
}</pre></li><li><p>在inde.js引入Promise</p><pre class='md-fences mock-cm' style='display:block;position:relative'>首先导入
const fetch = require(&quot;../../utils/fetch.js&quot;)

当发起请求时：
//获取轮播图信息
    fetch(&#39;slides&#39;).then(res=&gt;{
      this.setData({ slides: res.data })
})</pre></li></ul><h3><a name='header-c575' class='md-header-anchor '></a>13、页面间跳转：</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;navigator url=&quot;{{item.link}}&quot; wx:if=&quot;{{item.link}}&quot;&gt;
       &lt;image src=&quot;{{ item.image }}&quot; mode=&#39;aspectFill&#39;&gt;&lt;/image&gt;
&lt;/navigator&gt;</pre><ul><li><p>主页面（tabBar中页面）没有办法，通过navigator切换</p><pre class='md-fences mock-cm' style='display:block;position:relative'>- 只能新建页面，并且页面并没有设置到tabBar中
- 点击navigator之后，在对应页面的onLoad事件中可以通过option形参接收到传递过来的参数</pre></li></ul><h3><a name='header-c582' class='md-header-anchor '></a>14、url为空navigator会出问题</h3><p>原因：</p><ul><li><p>1、link为空</p></li><li><p>2、navigator工作会出问题</p></li><li><p>3、样式 :</p><pre class='md-fences mock-cm' style='display:block;position:relative'>.slides navigator,
.slides image {
  width: 100%;
  height: 100%;
}</pre></li></ul><h3><a name='header-c596' class='md-header-anchor '></a>15、使用wx:if条件渲染</h3><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;navigator url=&quot;{{item.link}}&quot; wx:if=&quot;{{item.link}}&quot;&gt;
       &lt;image src=&quot;{{ item.image }}&quot; mode=&#39;aspectFill&#39;&gt;&lt;/image&gt;
&lt;/navigator&gt;

&lt;image wx:else src=&quot;{{ item.image }}&quot; mode=&#39;aspectFill&#39;&gt;&lt;/image&gt;</pre><p></p><h1><a name='header-c600' class='md-header-anchor '></a>列表页面实现：</h1><p>1、获取分类信息</p><pre class='md-fences mock-cm' style='display:block;position:relative'>onLoad: function (options) {
    // console.log(options.cat)
    // 获取分类信息
    return fetch(`categories/${options.cat}`).then(res =&gt; {
      // console.log(res)
      this.setData({ category: res.data })
      if (res.data.name) {
        //设置当前页面名称
        wx.setNavigationBarTitle({
          title: res.data.name
        })

        //根据分类获取商品列表信息
        this.loadMore()
      }
    })
  }</pre><p>首页传递到列表页，需要带参数：</p><pre class='md-fences mock-cm' style='display:block;position:relative'>&lt;navigator url=&quot;/pages/cate/cate?cat={{item.id}}&quot; class=&quot;item&quot; wx:for=&quot;{{ categories }}&quot; wx:key=&quot;id&quot;&gt;
    &lt;image src=&quot;{{ item.icon}}&quot;&gt;&lt;/image&gt;
    &lt;text&gt;{{ item.name }}&lt;/text&gt;
&lt;/navigator&gt;
列表页通过options接收</pre><h2><a name='header-c607' class='md-header-anchor '></a>1、修改页面标题：</h2><ul><li>只写在onLoad中设置标题名不合适</li></ul><p>原因：</p><ul><li><p>1、页面渲染完成后才只能设置页面标题</p></li><li><p>2、页面渲染完成：onReady，需要在设置一次（考虑网速快的情况）</p><pre class='md-fences mock-cm' style='display:block;position:relative'>/*** 生命周期函数--监听页面初次渲染完成*/
  onReady: function () {
    console.log(this.data.category)
    if (this.data.category.name) {
      //设置当前页面名称
      wx.setNavigationBarTitle({
        title: this.data.category.name
      })
    }
  }</pre><p>​</p></li></ul><h1><a name='header-c624' class='md-header-anchor '></a>上拉加载更多数据样式</h1><p>1、自定义加载下一页函数</p><pre class='md-fences mock-cm' style='display:block;position:relative'>// 自定义加载下一页函数
  loadMore() {
    if (!this.data.haseMore) {
      let { pageIndex, pageSize } = this.data
      const params = { _page: ++pageIndex, _limit: pageSize }//页码自增
      return fetch(`categories/${this.data.category.id}/shops`, params)
        .then(res =&gt; {
          console.log(res.data.length)
          const totalCount = parseInt(res.header[&#39;X-Total-Count&#39;])
          const haseMore = pageIndex * pageSize &gt; totalCount
          console.log(haseMore)
          // if (res.data.length == 0) {
          //     console.log(&#39;没有更多数据了&#39;);
          //     return
          // }
          const shops = this.data.shops.concat(res.data)//拼接商品列表信息
          this.setData({ shops: shops, pageIndex: pageIndex, haseMore: haseMore })
        })
    }
  }</pre><p></p></div>
</body>
</html>